package org.erepublik.company.scanner;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;

import org.erepublik.company.ECountry;
import org.erepublik.company.EProductType;
import org.erepublik.company.comparators.ProductComparatorByPriceInGold;
import org.erepublik.company.product.EProductAttribute;
import org.erepublik.company.product.ProductDesign;
import org.erepublik.company.product.ProductKey;
import org.erepublik.company.product.Weapons;
import org.erepublik.company.service.ICompanyCountryService;
import org.erepublik.company.service.IVatService;
import org.erepublik.company.service.InternetCompanyCountryService;
import org.erepublik.company.service.JSONExchangeRateService;
import org.erepublik.company.service.XmlVatService;

public class WeaponScanner extends ProductScanner<Weapons> {



    public WeaponScanner(EProductType productType) {
        this.productType = productType;
    }

    @Override
    protected Weapons[] getEmptyTable() {
        return new Weapons[0];
    }

    @Override
    protected Weapons getNewProduct() {
        return new Weapons(productType);
    }

    @Override
    protected Weapons[] getProductsFromCountry(ECountry country, IVatService vatService, ICompanyCountryService companyService,
            JSONExchangeRateService currency) throws Exception {
        ProductDesign productDesign = new ProductDesign(EProductType.HELICOPTER);
        HashMap<ProductKey, Weapons> map = new HashMap<ProductKey, Weapons>();

        ArrayList<WeaponCutValue> cutValue = new ArrayList<WeaponCutValue>();
        ArrayList<WeaponCutValue> topCutValue = new ArrayList<WeaponCutValue>();
        for (int i = 0; i <= 100; i += 10) {
                    for (int l = 0; l <= 100; l += 10) {
                
                        if (!isWorthChecking(i, l, cutValue, topCutValue))
                            continue;
                        productDesign.setAttributeValue(EProductAttribute.ATTACK, i); //dmg
                        productDesign.setAttributeValue(EProductAttribute.DEFENSE, l); //dur
                                  
                        Weapons[] scannedProducts = getProductList(country, productDesign, vatService, companyService, currency);
                        WeaponCutValue topCut = getMinimalAttributes(scannedProducts);
                        topCutValue.add(topCut);
                        if (scannedProducts.length < 10)
                            cutValue.add(new WeaponCutValue(i ,l));
                        for (Weapons product : scannedProducts) {
                            ProductKey key = new ProductKey(product.getCompanyOwner().getId(), country);
                            if (!map.containsKey(product)) {
                                map.put(key, product);
                            }
                        }
             
            }
        }
        Weapons[] products = map.values().toArray(new Weapons[0]);
        Arrays.sort(products, new ProductComparatorByPriceInGold());
        return products;

    }

    private WeaponCutValue getMinimalAttributes(Weapons[] scannedProducts) {

        int mindmg=100;
        int mindur=100;
        for (int i=0; i < scannedProducts.length; i++) {

            if (mindmg > scannedProducts[i].getProductDesign().getAttributeValue(EProductAttribute.DAMAGE))
                mindmg = scannedProducts[i].getProductDesign().getAttributeValue(EProductAttribute.DAMAGE);
            if (mindur > scannedProducts[i].getProductDesign().getAttributeValue(EProductAttribute.DURABILITY))
                mindur = scannedProducts[i].getProductDesign().getAttributeValue(EProductAttribute.DURABILITY);
        }
        return new WeaponCutValue(mindmg,  mindur);
    }

    private boolean isWorthChecking(int i, int l, ArrayList<WeaponCutValue> cutValues, ArrayList<WeaponCutValue> topCutValue) {
        for (WeaponCutValue cutValue : cutValues) {
            if (i >= cutValue.getVutValue1()
                    && l >= cutValue.getVutValue4())
                return false;
        }
        for (WeaponCutValue cutValue : topCutValue) {
            if (i <= cutValue.getVutValue1() 
                    && l <= cutValue.getVutValue4()) {
                return false;
            }
        }
        return true;
    }

 
    
    
    public static void main(String[] args) throws Exception {
        WeaponScanner scanner = new WeaponScanner(EProductType.RIFLE);
    
//        Weapons[] weapons  = scanner.getProductsFromCountry(ECountry.SLOVENIA, new XmlVatService(), new InternetCompanyCountryService(), new JSONExchangeRateService());

        Weapons[] weapons = scanner.getProductsFromAllCountries(new XmlVatService(), new InternetCompanyCountryService(), new JSONExchangeRateService());
        
        Arrays.sort(weapons, new ProductComparatorByPriceInGold());
//        weapons = filter(100, 0, 30, 100, weapons);
        
        for (Weapons weapons2 : weapons) {
            System.out.println(weapons2.getCountry() + " " + weapons2.getPrice() + weapons2.getCountry().getCurrencyName() + " " + weapons2.getPriceInGold() + "g " +weapons2.getQuantity() + " "+weapons2.getProductDesign());
        }
        System.out.println("w sumie "+weapons.length);
    }
    
    
    
    public static Weapons[] filter(int minDur, int minDmg, Weapons[] weapons) {
        ArrayList<Weapons> newList = new ArrayList<Weapons>();
        for (Weapons weapon : weapons) {
            ProductDesign design = weapon.getProductDesign();

            int dur = design.getAttributeValue(EProductAttribute.DURABILITY);
            int dmg = design.getAttributeValue(EProductAttribute.DAMAGE);
            if (dur >= minDur && dmg >= minDmg)
                newList.add(weapon);
        }
        return newList.toArray(new Weapons[0]);
    }
    
    
    
    
    
    
}






class WeaponCutValue {
    private int cutValue1 = 0;

    private int cutValue4 = 0;

    public WeaponCutValue(int cutValue1, int cutValue4) {
        this.cutValue1 = cutValue1;
 
        this.cutValue4 = cutValue4;
    }

    public int getVutValue1() {
        return cutValue1;
    }



    public int getVutValue4() {
        return cutValue4;
    }

}